package com.example.消息可靠性.发送方保证.事务方式;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager;

/**
 * 1.客户端发出请求，将信道设置为事务模式。
 * 2.服务端给出回复，同意将信道设置为事务模式。
 * 3.客户端发送消息。
 * 4.客户端提交事务。
 * 5.服务端给出响应，确认事务提交。
 */
//@Configuration
public class TranConfig {
    public static final String TRAN_QUEUE = "tran_queue";
    public static final String TRAN_EXCHANGE = "tran_exchange";

    //@Bean
    Queue tranQueue() {
        return new Queue(TRAN_QUEUE, true, false, false);
    }

    /**
     * 定义一个直连交换机
     *
     * @return
     */
    //@Bean
    DirectExchange tranExchange() {
        //1. 交换机的名称
        //2。交换机是否持久化
        //3. 如果没有与之绑定的队列，是否删除交换机
        return new DirectExchange(TRAN_EXCHANGE, true, false);
    }

    /**
     * 这个定义是将交换机和队列绑定起来
     *
     * @return
     */
    //@Bean
    Binding tranBinding() {
        return BindingBuilder
            .bind(tranQueue()).to(tranExchange()).with(TRAN_QUEUE);
    }

    /**
     * 提供事务管理器
     * @param connectionFactory
     * @return
     */
    //@Bean
    RabbitTransactionManager transactionManager(ConnectionFactory connectionFactory) {
        return new RabbitTransactionManager(connectionFactory);
    }


    //@Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //指示此组件创建的通道将是事务性的标志
        rabbitTemplate.setChannelTransacted(true);
        return rabbitTemplate;
    }
}
